﻿using DataBase.DBmodels;
using DataBase.Utils;
using GreenXi.Help;
using GreenXi.Job;
using GreenXi.Pages.Power;
using S7.Net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Util;
using Util.Model;
using ZedGraph;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Text.Json.Nodes;
using System.Net.Http.Json;
using Quartz.Logging;
using System.Net.Http;
using Helpers;
using System.Diagnostics;
using static GreenXi.GlobalVariables;
using GreenXi.Help.PLC;
using GreenXi.Help.Curve;
using GreenXi.Help.Plc;
using PressSystem_Can.Help.Can;
using ModbusHelper;
using GreenXi.Help.Can;
using LiveCharts;
using MySqlX.XDevAPI;
using ProductionData = DataBase.DBmodels.ProductionData;
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualBasic;

namespace GreenXi.ViewModel.Utils
{
    public class PressUtil
    {
        //判断是否触发误差判断
        private static bool ISErrorJudgment1;
        private static bool ISErrorJudgment2;

        

        private void SetCurrentMaxDisplacementAndPressureData(int nAxisNum,double currentMaxDisplacement, double currentMaxPressure)
        {
            if (nAxisNum == 1)
            {
                GlobalVariables.CurrentMaxDisplacement1 = currentMaxDisplacement;
                GlobalVariables.CurrentMaxPressure1 = currentMaxPressure;
                PressureCurve.Instance.CurrentMaxDisplacement1 = (double)GlobalVariables.CurrentMaxDisplacement1;
                PressureCurve.Instance.CurrentMaxPressure1 = (double)GlobalVariables.CurrentMaxPressure1;
                if (Manual.Instance != null)
                {
                    Manual.Instance.CurrentMaxDisplacement1 = (double)GlobalVariables.CurrentMaxDisplacement1;
                    Manual.Instance.CurrentMaxPressure1 = (double)GlobalVariables.CurrentMaxPressure1;
                }
            }
            else
            {
                GlobalVariables.CurrentMaxDisplacement2 = currentMaxDisplacement;
                GlobalVariables.CurrentMaxPressure2 = currentMaxPressure;
                PressureCurve.Instance.CurrentMaxDisplacement2 = (double)GlobalVariables.CurrentMaxDisplacement2;
                PressureCurve.Instance.CurrentMaxPressure2 = (double)GlobalVariables.CurrentMaxPressure2;
                if (Manual.Instance != null)
                {
                    Manual.Instance.CurrentMaxDisplacement2 = (double)GlobalVariables.CurrentMaxDisplacement2;
                    Manual.Instance.CurrentMaxPressure2 = (double)GlobalVariables.CurrentMaxPressure2;
                }
               
            }
        }

        

        #region 合格判定
        public void QualificationAndDisplay(PointPairList ListPress, int nAxisNum, string model, bool result, string funcName = null)
        {
            using MyDbContext myDbContext = new();

            PLC1 plc = new();



            // 判断是否合格
            if (result)
            {
                result = SmoothChart.SmoothChartResult(ListPress, myDbContext.GetDecisionByFuncName(funcName, nAxisNum.ToString()));
            }

            string qualifiedStatus = result ? "Green" : "Red";

            short status = result ? (short)1 : (short)2;

            try
            {
                //获取本身最大位移
                double maxdisp = 0;
                    if (ListPress!=null&& ListPress.Count>0)
                {
                    maxdisp=ListPress.MaxBy(x => x.X).X;
                }
				//获取压装程序最大位移
				if (nAxisNum == 1)
				{
					if (Math.Abs(maxdisp - (double)GlobalVariables.CurrentMaxDisplacement1) > 0.3)
					{

						GlobalVariables.IsProtectDisplacement1 = true;
					}
					else
					{
						GlobalVariables.IsProtectDisplacement1 = false;
					}
				}
				else
				{
					if (Math.Abs(maxdisp - (double)GlobalVariables.CurrentMaxDisplacement2) > 0.3)
					{

						GlobalVariables.IsProtectDisplacement2 = true;
					}
					else
					{
						GlobalVariables.IsProtectDisplacement2 = false;
					}

				}
			}
            catch(Exception e)
            {
                Helpers.Logger.Instance.Warning(e.Message);
            }
           


			//if ((IsProtectStop1 == true && nAxisNum == 1&&GlobalVariables.IsProtectDisplacement1 ) || (IsProtectStop2 == true && nAxisNum == 2&&GlobalVariables.IsProtectDisplacement2))
   //         {
   //             Helpers.Logger.Instance.Infomation($"压机{nAxisNum} qualified red,protectstop1:{IsProtectStop1} ,ProtectDisp1:{GlobalVariables.IsProtectDisplacement1} ,protectDisplay2:{GlobalVariables.IsProtectDisplacement2}");
			//		qualifiedStatus = "Red";
			//}

            if (GlobalVariables.IsForcedStop)
            {
				Helpers.Logger.Instance.Infomation($"压机{nAxisNum} IsForcedStop red");

				qualifiedStatus = "Red";
            }

            if (model == "手动")
            {
                if (nAxisNum == 1)
                {
                    Manual.Instance.IsQualified1 = qualifiedStatus;
                }
                else
                {
                    Manual.Instance.IsQualified2 = qualifiedStatus;
                }
            }
            else
            {
                if (nAxisNum == 1)
                {
                    PressureCurve.Instance.IsQualified1 = qualifiedStatus;
                }
                else
                {
                    PressureCurve.Instance.IsQualified2 = qualifiedStatus;
                }
            }

            //合格信息给PLC
            if (GlobalVariables.IsForcedStop)
            {
                plc.SetPLC($"MES_Assess{nAxisNum}", (short)2);
            }
            else
            {
                if (IsProtectStop1 == true && nAxisNum == 1)
                {
                    plc.SetPLC($"MES_Assess1", (short)2);
                }
                else if (IsProtectStop2 == true && nAxisNum == 2)
                {
                    plc.SetPLC($"MES_Assess2", (short)2);
                }
                else
                {
                    plc.SetPLC($"MES_Assess{nAxisNum}", status);
                }
            }
        }

        #endregion

        #region 判断是否可以执行压装程序
        /// <summary>
        /// 判断是否可以执行压装程序
        /// </summary>
        /// <param name="nAxisNum">轴号</param>
        /// <returns></returns>
        public bool CheckStatus(int nAxisNum)
        {
            if (nAxisNum == 1)
            {
                return GlobalVariables.Card_Mode1 == 1
                    && !GlobalVariables.IsForcedStop
                    && !GlobalVariables.IsServoAlarm
                    && !GlobalVariables.IsLostDisplacementData;
            }
            else
            {
                return GlobalVariables.Card_Mode2 == 1
                    && GlobalVariables.Plc_Status2 == 1
                    && !GlobalVariables.IsForcedStop
                    && !GlobalVariables.IsServoAlarm
                    && !GlobalVariables.IsLostDisplacementData;
            }
        }
        #endregion

        #region 根据压装程序执行
        /// <summary>
        /// 根据压装程序执行
        /// </summary>
        /// <param name="nAxisNum">轴号</param>
        /// <param name="CraftList">压装程序</param>
     

        private void SetIsWaiting(int nAxisNum, bool status)
        {
            if (nAxisNum == 1)
            {
                GlobalVariables.IsWaiting1 = status;
            }
            else if (nAxisNum == 2)
            {
                GlobalVariables.IsWaiting2 = status;
            }
        }

        private async Task WaitUntilCompressor1And2NotRunning()
        {
            while (!(GlobalVariables.IsWaiting1 && GlobalVariables.IsWaiting2))
            {
                await Task.Delay(20);
            }
        }
        #endregion

        #region 获取压装数据中的最大力和最大位移
        private void SetMaxPressureAndDisplacementToPLC(int nAxisNum, PointPairList ListPress)
        {
            var MaxDisplacement = ListPress.Max(point => point.X);
            var MaxPressure = ListPress.Max(point => point.Y);
            PLC1 plc = new();
            plc.SetPLC<float>($"MES_MaxDisplacement{nAxisNum}", (float)MaxDisplacement);
            plc.SetPLC<float>($"MES_MaxPressure{nAxisNum}", (float)MaxPressure);

            SetCurrentMaxDisplacementAndPressureData(nAxisNum, MaxDisplacement, MaxPressure);
        }
        #endregion

        
  



        

        

        #region 判断是否误差范围内
        private static bool IsReasonable(double Card_Displacement, double maxDisp)
        {
            //判断位移误差 超出范围给ng并且直接回来
            if (Math.Abs(Card_Displacement - maxDisp) > 0.3)
            {
                //给 PLC NG
                return false;
            }
            return true;
        }
        #endregion

        

        #region 压装数据处理并存入数据库
        /// <summary>
        /// 将数据点存入数据库
        /// </summary>
        /// <returns></returns>
        public async Task SaveProductionDataLogAsync(PointPairList List,int count,int ID,int ? sn, int type, string name="")
        {
            MyDbContext myDbContext = new();
            List<ProductionData> productionList = new();
            var ListCount = List.Count;
            try
            {
               if(List==null|| List.Count == 0)
                {
                    return;
                }
                ProductionData productionLog = new ProductionData
                {
                    CylinderNo = ID,
                    Result = name==null?"":name,
                    MaxPositionValue = List.Last().Y,
                    MaxPressureValue = List.Last().X,
                    NowTime = List.Last().Tag.ToString(),
                    Sn = sn.ToString(),
                    Type= type,
                    CreateTime = DateTime.Now,
                };
                productionList.Add(productionLog);
                await myDbContext.AddRangeAsync(productionList);
                myDbContext.SaveChanges();
            }
            catch (Exception ex) {
                Helpers.Logger.Instance.Error(ex,"存储点位报错");
            }
           
        }

        public async Task SaveProductionDataLogAsync2(CraftView view)
        {
            MyDbContext myDbContext = new();
            List<ProductionData> productionList = new();

            try
            {
                ProductionData productionLog = new ProductionData
                {
                    CylinderNo = view.Id,
                    Result = view.Project == null ? "" : view.Project,
                    MaxPositionValue = view.Humidity_A,
                    MaxPressureValue = view.Humidity_B,
                    NowTime= view.Humidity_C.ToString(),
                    Type =view.Type.Value,
                    Sn =view.CraftId.ToString(),
                    CreateTime = DateTime.Now,
                };
                productionList.Add(productionLog);
                await myDbContext.AddRangeAsync(productionList);
                myDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                Helpers.Logger.Instance.Error(ex, "存储点位报错");
            }

        }
        #endregion

        #region 对ModbusTcp获取的数据进行赋值
        /// <summary>
        /// </summary>

        public static void AssignmentCraftView(ushort[] getInfo)
        {
            var CraftViewList = GlobalVariables.CraftViewList;
            // 确保 CraftViewList 不为空
            if (CraftViewList == null || CraftViewList.Count == 0)
                return;

            // 遍历 getInfo 数组
            for (int i = 0; i < getInfo.Length; i++)
            {
                // 计算当前组索引
                int groupIndex = i / 6;

                // 如果超出 CraftViewList 的范围，退出循环
                if (groupIndex >= CraftViewList.Count)
                    break;

                // 获取当前组的 CraftView 对象
                var craftView = CraftViewList[groupIndex];

                // 计算当前元素在组内的位置
                int positionInGroup = i % 6;

               
            }
            GlobalVariables.CraftViewList=CraftViewList;
        }
        #endregion

        #region 画线方法
        public async Task DrawlineAsync()
        {
            ///获取当前电表数量
            
            int count = GlobalVariables.CraftViewList.Count;
            for (int i = 0; i < count; i++)
            {
                if (GlobalVariables.CraftViewList[i].Gather > GlobalVariables.CraftViewList[i].GatherCount || GlobalVariables.CraftViewList[i].Gather == null)
                {
                    GlobalVariables.CraftViewList[i].GatherCount++;
                    continue;
                }
                GlobalVariables.CraftViewList[i].GatherCount = 0;
                ListPress[i].Add(new PointPair(
                     new XDate(DateTime.Now),
                       Convert.ToDouble(GlobalVariables.CraftViewList[i].Energy),
                       DateTime.Now.ToString()
                    ));
            }
            PressureCurve.AxisChange(1);
        }
        #endregion

        #region 报警判定
        public async Task IsCallPoliceAsync()
        {
            bool IsPolice = false;
            try
            {

           
            for (int i = 0; i < GlobalVariables.CraftViewList.Count; i++)
            {
                //是否启用报警
                if (GlobalVariables.CraftViewList[i].IsCallPolice&& GlobalVariables.ListPress[i].Count>0)
                {
                    var lastPonit = GlobalVariables.ListPress[i].LastOrDefault();
                    //启用报警,判断是否超过限位总功率
                    if (lastPonit.Y> GlobalVariables.CraftViewList[i].StartPoint)
                    {
                        IsPolice = true;
                         PoliceStr = $"电表" + GlobalVariables.CraftViewList[i].Project + Enum.GetName(typeof(CallPoliceStatus), 10);
                        GlobalVariables.CallPolice = 10;
                        return;
                    }
                   int  TimeResult = IsPeakOrValley();
                    if (TimeResult == 1)
                    {
                        //时间在峰谷时间
                        if (lastPonit.Y > GlobalVariables.CraftViewList[i].PeakLimitation)
                        {
                            IsPolice = true;
                            PoliceStr = $"电表" + GlobalVariables.CraftViewList[i].Project + Enum.GetName(typeof(CallPoliceStatus), 20);
                            GlobalVariables.CallPolice = 20;
                            return;
                        }
                    }
                    else if (TimeResult == 2) {
                        //时间在谷谷时间
                        if (lastPonit.Y > GlobalVariables.CraftViewList[i].ValleyLimitation)
                        {
                            IsPolice = true;
                            PoliceStr = $"电表" + GlobalVariables.CraftViewList[i].Project + Enum.GetName(typeof(CallPoliceStatus), 30);
                            GlobalVariables.CallPolice = 30;
                            return;
                        }
                    }
                   
                }
            }

            for (int i = 0; i < GlobalVariables.CraftViewList2.Count; i++)
            {
                //是否启用报警
                if (GlobalVariables.CraftViewList2[i].IsCallPolice  )
                {
                    //启用报警,判断是否超过限位总功率
                    if (GlobalVariables.CraftViewList2[i].Humidity_A > GlobalVariables.CraftViewList2[i].StartPoint)
                    {
                        IsPolice = true;
                        PoliceStr = $"温湿度表" + GlobalVariables.CraftViewList2[i].Project + Enum.GetName(typeof(CallPoliceStatus), 50);
                        GlobalVariables.CallPolice = 10;
                        return;
                    }
                }
            }
            for (int i = 0; i < GlobalVariables.CraftViewList3.Count; i++)
            {
                //是否启用报警
                if (GlobalVariables.CraftViewList3[i].IsCallPolice )
                {
                    //启用报警,判断是否超过限位总功率
                    if (GlobalVariables.CraftViewList3[i].Humidity_A > GlobalVariables.CraftViewList3[i].StartPoint|| (GlobalVariables.CraftViewList3[i].Humidity_B > GlobalVariables.CraftViewList3[i].StartPoint||GlobalVariables.CraftViewList3[i].Humidity_C > GlobalVariables.CraftViewList3[i].StartPoint))
                    {
                        IsPolice = true;
                        PoliceStr = $"变压器温度表" + GlobalVariables.CraftViewList3[i].Project + Enum.GetName(typeof(CallPoliceStatus), 50);
                        GlobalVariables.CallPolice = 10;
                        return;
                    }
                }
                }
            if (!IsPolice) {
                PoliceStr = "";
                GlobalVariables.CallPolice = 0;
            }

             }
            catch (Exception ex) { 
            
            }
        }

        /// <summary>
        /// 判断该当前时间是峰还是谷 0都不是 1峰 2 谷 
        /// </summary>
        /// <returns></returns>
        public int IsPeakOrValley()
        {
            int result = 0;

            // 获取当前时间
            TimeSpan now = DateTime.Now.TimeOfDay;
            foreach (var item in GlobalVariables.TimeslotList)
            {
                TimeSpan startTime = TimeSpan.Parse(item.StartTime);
                TimeSpan endTime = TimeSpan.Parse(item.EndTime);
                if (now >= startTime && now <= endTime) {

                    return item.Type == "峰段" ? 1 : 2;
               
                }
            }
                return result;
        }
        #endregion
    }
}
